﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace CudaCluster
{
    public partial class Form1 : Form
    {
        int rows;
        int numcolumns;
        string[] name;
        string[] columns;
        float[,] cells;
        float[] linkage;
        public Form1()
        {
            InitializeComponent();
        }
        private void Open_Click(object sender, EventArgs e)
        {
            openFileDialog1.ShowDialog();
            string path = openFileDialog1.FileName;
            rows = Convert.ToInt32(textBox1.Text);
            numcolumns = Convert.ToInt32(textBox2.Text);
            ReadFile(path, rows);
        }
        private void ReadFile(string path, int rows)
        {
            StreamReader sr = new StreamReader(path);
            name = new string[rows];
            columns = new string[7];
            cells = new float[rows,7];
            string temp;
            string[] seperator = new string[1];
            seperator[0] = "\t";
            string[] temp1 = new string[10];
            temp = sr.ReadLine();
            temp1 = temp.Split(seperator, 10, System.StringSplitOptions.None);
            for (int k = 0; k < 7; k++)
            {
                columns[k] = temp1[k + 3];
            } 
            sr.ReadLine();
           
            char[] c = new char[7];
            for (int i = 0; i < rows; i++)
            {
                temp = sr.ReadLine();
                temp1 = temp.Split(seperator, 10, System.StringSplitOptions.None);
                name[i] = temp1[0] + "\t" + temp1[1];
                for (int j = 0; j < 7; j++)
                {
                    cells[i, j] = Convert.ToSingle(temp1[j + 3]);
                }
            }
            float[] input = new float[rows * numcolumns];
            int k2 = 0;
            for (int i = 0; i < numcolumns; i++)
            {
                for (int j = 0; j < rows; j++)
                {
                    input[k2] = cells[j, i];
                    k2++;
                }
            }
            CudaCalls.CallCudaFunction cc = new CudaCalls.CallCudaFunction();
            float[] pdist = cc.Call_run_pdist(input, Convert.ToUInt32(numcolumns), Convert.ToUInt32(rows));
            pdist = cc.Call_lower_triangle(pdist, Convert.ToUInt32(rows));
            linkage = cc.Call_run_linkage(pdist, Convert.ToUInt32(rows));
            OutputCDT();
        }
        private void OutputCDT() 
        {
            string col ="";
            string arr ="";
            string eweight = "";
            string cel = "";
            for (int i = 0; i < numcolumns; i++)
            {
                col += "\t" + columns[i];
            }
            StreamWriter sw = new StreamWriter("C:/Program Files/Stanford University/Cluster/sample.cdt");
            sw.WriteLine("GID\tYORF\tNAME\tGWEIGHT" + col);
            for (int j = 0; j < numcolumns; j++)
            {
                arr += "\tARRY" + j + "X";
            }
            sw.WriteLine("AID\t\t\t" + arr);
            for (int k = 0; k < numcolumns; k++)
            {
                eweight += "\t1";
            }
            sw.WriteLine("EWEIGHT\t\t\t" + eweight);
            for (int i = 0; i < linkage.Length; i++)
            {
                if ((i + 1) % 3 == 0)
                    continue;

                if (linkage[i] <= Convert.ToUInt32(rows))
                {
                    for (int l = 0; l < numcolumns; l++)
                    {
                        cel += "\t" + Convert.ToString(cells[(int)linkage[i] - 1, l]);
                    }
                    sw.WriteLine("GENE" + ((int)linkage[i] - 1) + "X\t" + name[(int)linkage[i] - 1] + "\t1" + cel);
                    cel = "";
                }
            }
            /*
            for(int i = 0; i<rows;i++)
            {
                for(int l = 0; l<numcolumns;l++)
                {
                    cel += "\t" + Convert.ToString(cells[i,l]);
                }
                sw.WriteLine("GENE" + i + "X\t" + name[i] + "\t1" + cel);
                cel = "";
            }
             */
            sw.Dispose();
            sw.Close();
            OutputGTR();
        }
        private void OutputGTR()
        {   
            StreamWriter sw = new StreamWriter("C:/Program Files/Stanford University/Cluster/sample.gtr");
            string[] gtr = new string[Convert.ToUInt32(rows)-1];
            int n = 0;
            for (int j = 0; j < linkage.Length;j=j+3)
            {
                if (linkage[j] <= Convert.ToUInt32(rows))
                {
                    if (linkage[j + 1] <= Convert.ToUInt32(rows))
                    {
                        gtr[n] = "NODE" + (n + 1) + "X\tGENE" + (linkage[j]-1) + "X\tGENE" + (linkage[j + 1]-1) + "X\t" + DistanceToCorrelation(linkage[j + 2]);
                        n++;
                    }
                    else
                    {
                        gtr[n] = "NODE" + (n + 1) + "X\tGENE" + (linkage[j]-1) + "X\tNODE" + Convert.ToInt32(linkage[j + 1] - Convert.ToUInt32(rows)) + "X\t" + DistanceToCorrelation(linkage[j + 2]);
                        n++;
                    }
                }
                else
                {
                    gtr[n] = "NODE" + (n + 1) + "X\tNODE" + Convert.ToInt32(linkage[j] - Convert.ToUInt32(rows)) + "X\tNODE" + Convert.ToInt32(linkage[j + 1] - Convert.ToUInt32(rows)) + "X\t" + DistanceToCorrelation(linkage[j + 2]);
                    n++;
                }
            }
            for (int l = 0; l < Convert.ToUInt32(rows)-1; l++)
            {
                sw.WriteLine(gtr[l]);
            }
            sw.Dispose();
            sw.Close();
            OutputATR();
        }
        private void OutputATR()
        {
            StreamWriter sw = new StreamWriter("C:/Program Files/Stanford University/Cluster/sample.atr");
            sw.WriteLine("NODE1X\tARRY0X\tARRY1X\t1");
            for (int i = 2; i < numcolumns; i++)
            {
                sw.WriteLine("NODE" + i + "X\tNODE" + (i - 1) + "X\tARRY" + i + "X" + "\t1");
            }
            sw.Dispose();
            sw.Close();
        }
        private float DistanceToCorrelation(float input)
        {
            if (input == 0)
                return 1;

            return 1.0f / input;
        }

    }
}
